#include "gpio.h"
#include "gpio_hw.h"

static GPIO_Struct *GPIO_Device(GPIO_PortEnum port)
{
	uint32_t addr = (uint32_t)&SOC_GPIOA;
	addr += port * 0x400;
	return (GPIO_Struct *)addr;
}

void GPIO_Init(const GPIO_InitStruct *gpioInit)
{
	GPIO_Struct *Gpio = GPIO_Device(gpioInit->port);
	uint32_t pin2 = gpioInit->pin * 2;
	uint32_t mask2 = ~(0x3U << pin2);

	/* 配置输入、输出、复用、模拟 */
	Gpio->MODER &= mask2;
	Gpio->MODER |= (uint32_t)gpioInit->mode << pin2;
	/* 配置推挽、开漏 */
	Gpio->OTYPER |= (uint32_t)gpioInit->otype << gpioInit->pin;
	/* 配置速度 */
	Gpio->OSPEEDR &= mask2;
	Gpio->OSPEEDR |= (uint32_t)gpioInit->ospeed << pin2;
	/* 配置上拉、下拉 */
	Gpio->PUPDR &= mask2;
	Gpio->PUPDR |= (uint32_t)gpioInit->pupd << pin2;
	/* 配置复用 */
	uint32_t off;
	_RW *reg;
	if (gpioInit->pin < 8) {
		reg = &Gpio->AFLR;
		off = gpioInit->pin * 4;
	} else {
		reg = &Gpio->AFHR;
		off = (gpioInit->pin - 8) * 4;
	}
	*reg &= ~(0xFU << off);
	*reg |= (uint32_t)gpioInit->af << off;
}
